package Registry;

import java.rmi.AccessException;
import java.rmi.AlreadyBoundException;
import java.rmi.NotBoundException;
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.RemoteServer;
import java.rmi.server.ServerNotActiveException;
import java.rmi.server.UnicastRemoteObject;
import java.util.HashMap;


public class RegistryImplementation extends UnicastRemoteObject implements Registry {
	private static final long serialVersionUID = 1L;
	
	private int fPort;
	private HashMap<String, String> fServicesClients = new HashMap<String, String>();

	public RegistryImplementation(int port) throws RemoteException {
		fPort = port;
		LocateRegistry.createRegistry(fPort);
	}

	public void rebind(String arg0, Remote arg1) throws RemoteException {
		try {
			if (fServicesClients.containsKey(arg0)) {
				if (RemoteServer.getClientHost().toString().equalsIgnoreCase(fServicesClients.get(arg0))) {
					LocateRegistry.getRegistry(fPort).rebind(arg0, arg1);
				} else {
					System.out.println("[ERROR] Client " + RemoteServer.getClientHost().toString() + " can't rebind, service was binded by " + fServicesClients.get(arg0));
				}
			} else {
				LocateRegistry.getRegistry(fPort).rebind(arg0, arg1);
				fServicesClients.put(arg0, RemoteServer.getClientHost().toString());
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public void bind(String arg0, Remote arg1) throws RemoteException,AlreadyBoundException, AccessException {
		try {
			LocateRegistry.getRegistry(fPort).bind(arg0, arg1);
			fServicesClients.put(arg0, RemoteServer.getClientHost().toString());
		} catch (ServerNotActiveException e) {
			e.printStackTrace();
		}
	}

	public String[] list() throws RemoteException, AccessException {
		return LocateRegistry.getRegistry(fPort).list();
	}

	public Remote lookup(String arg0) throws RemoteException,NotBoundException, AccessException {
		return LocateRegistry.getRegistry(fPort).lookup(arg0);
	}

	public void unbind(String arg0) throws RemoteException, NotBoundException,AccessException {
		try {
			if (fServicesClients.containsKey(arg0)) {
				if (RemoteServer.getClientHost().toString().equalsIgnoreCase(fServicesClients.get(arg0))) {
					LocateRegistry.getRegistry(fPort).unbind(arg0);
					fServicesClients.remove(arg0);
				} else {
					System.out.println("[ERROR] Client " + RemoteServer.getClientHost().toString() + " can't unbind, service was binded by " + fServicesClients.get(arg0));
				}
			} 
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}
